package com.hnu.store.service.impl;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.hnu.store.entity.Case;
import com.hnu.store.mapper.CaseMapper;
import com.hnu.store.service.ICaseService;
import com.hnu.store.service.ex.CaseDeleteException;
import com.hnu.store.service.ex.CaseInsertException;
import com.hnu.store.service.ex.CaseUpdateException;
import com.hnu.store.service.ex.FileNotFoundException;
import com.hnu.store.service.ex.FileTypeException;
import com.hnu.store.service.ex.GetCaseException;
import com.hnu.store.service.ex.GetNewsException;
import com.hnu.store.service.ex.UploadException;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Random;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

@Service
public class CaseServiceImpl implements ICaseService {

    @Autowired
    private CaseMapper caseMapper;
    @Override
    public void addCase(Case case0, MultipartFile multipartFile) {
        String originalFilename = multipartFile.getOriginalFilename();
        //  获取文件类型
        String fileType = originalFilename.substring(originalFilename.indexOf('.')+1);
        if(!fileType.equals("jpg")&&!fileType.equals("png")&&!fileType.equals("webp")) {
            throw new FileTypeException("文件类型错误");
        }

        String dirName = "nftCase";
        //  生成id
        String id = IdWorker.getIdStr(case0);
        String path = System.getProperty("user.dir") + File.separator + dirName + File.separator + id;
        case0.setFilePath(path);
        case0.setId(id);

        if(multipartFile!=null) {
            String fileName = multipartFile.getOriginalFilename();
            case0.setFileName(fileName);
            case0.setPictureUrl("http://124.222.70.223:8081/case/getImg?filePath="+path+"&fileName="+fileName);
            //  生成文件目录
            File fileDir = new File(path);
            if (!fileDir.exists() && !fileDir.isDirectory()) {
                fileDir.mkdirs();
            }

            File file = new File(fileDir, Objects.requireNonNull(multipartFile.getOriginalFilename()));
            try {
                multipartFile.transferTo(file);
            } catch (IOException e) {
                throw new UploadException("案例封面上传异常");
            }
            //  上传封面成功，准备插入数据库
        } else {
            throw new CaseInsertException("未上传案例图片");
        }

        /*
        如果rows！=1代表插入失败，爆出异常
         */
        Integer rows = caseMapper.insertCase(case0);
        if (rows != 1){
            throw new CaseInsertException("插入案例过程中发生异常");
        }
    }

    @Override
    public void deleteCase(String id) {
        Case case0 = caseMapper.getCaseById(id);
        //  获取封面所在文件夹
        File dir = new File(case0.getFilePath());
        //  获取封面文件
        File file = new File(case0.getFilePath() + File.separator + case0.getFileName());
        if (!file.delete()) {
            throw new CaseDeleteException("删除案例封面出现异常");
        }

        if (!dir.delete()) {
            throw new CaseDeleteException("删除案例封面文件夹出现异常");
        }
        /*
        如果rows！=1代表删除失败，爆出异常
         */
        Integer rows = caseMapper.deleteCase(id);
        if (rows != 1){
            throw new CaseDeleteException("删除案例过程中发生异常");
        }
    }

    @Override
    public void editCase(Case case0,MultipartFile multipartFile) {
        String originalFilename = multipartFile.getOriginalFilename();
        //  获取文件类型
        String fileType = originalFilename.substring(originalFilename.indexOf('.')+1);
        if(!fileType.equals("jpg")&&!fileType.equals("png")&&!fileType.equals("webp")) {
            throw new FileTypeException("文件类型错误");
        }
        //  更新封面
        if(multipartFile!=null) {
            //  获取旧的新闻
            Case oldCase = caseMapper.getCaseById(case0.getId());
            String path = oldCase.getFilePath();
            case0.setFilePath(path);
            //  获取旧文件
            File oldFile = new File(path+File.separator+oldCase.getFileName());

            if (!oldFile.delete()) {
                System.out.println(oldFile.getPath());
                throw new CaseDeleteException("编辑时删除旧案例封面失败");
            }
            //  删除文件成功
            String fileName = multipartFile.getOriginalFilename();
            case0.setFileName(fileName);
            File file = new File(path, Objects.requireNonNull(multipartFile.getOriginalFilename()));
            //  上传封面
            try {
                multipartFile.transferTo(file);
            } catch (IOException e) {
                throw new CaseUpdateException("编辑时更新案例封面失败");
            }

            case0.setPictureUrl("http://124.222.70.223:8081/case/getImg?filePath="+path+"&fileName="+fileName);
            //  更新数据库
            Integer rows = caseMapper.updateCase(case0);
            /*
             如果rows！=1代表编辑失败，爆出异常
             */
            if(rows != 1){
                throw new CaseUpdateException("编辑案例过程中发生异常");
            }

        } else {
            //  不更新封面,只修改数据库即可
            Integer rows = caseMapper.updateCase(case0);
            /*
             如果rows！=1代表编辑失败，爆出异常
             */
            if(rows != 1){
                throw new CaseUpdateException("编辑新闻过程中发生异常");
            }
        }

    }

    @Override
    public ArrayList<Case> getCase() {
        //  获取所有案例
        ArrayList<Case> list = caseMapper.getCase();
        /*
        如果getCase == null代表获取失败，爆出异常
         */
        if (list == null){
            throw new GetCaseException("获取案例过程中发生异常");
        }

        return list;
    }

    @Override
    public ArrayList<Case> showCase() {
        //  获取所有案例
        ArrayList<Case> list = caseMapper.getCase();
        /*
        如果getCase == null代表获取失败，爆出异常
         */
        if (list == null){
            throw new GetCaseException("获取案例过程中发生异常");
        }

        //  随机选择五个案例返回
        int count = list.size();
        if(count<5) {
            throw new GetNewsException("案例数量小于5");
        }
        Random random = new Random();

        List<Integer> num = new ArrayList<>();
        while(num.size()<5) {
            int temp = random.nextInt(count);
            if(!num.contains(temp)) {
                num.add(temp);
            }
        }

        ArrayList<Case> caseList = new ArrayList<>();
        for (int i=0;i<5;i++) {
            caseList.add(list.get(num.get(i)));
        }
        return caseList;
    }

    @Override
    public void getImg(String filePath, String fileName, HttpServletResponse response) {

        //  根据文件路径获取文件
        File file = new File(filePath+File.separator+fileName);
        if (!file.exists()) {
            throw new FileNotFoundException("http请求的文件不存在");
        }

        //  配置文件下载
        response.setHeader("content-type", "application/octet-stream");
        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition",
            "attachment;filename=" + fileName);

        // 实现文件下载
        byte[] buffer = new byte[1024];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = response.getOutputStream();
            while ((fis.read(buffer)) != -1) {
                os.write(buffer);
                os.flush();
            }
            os.close();
        } catch (Exception e) {
            System.out.println("写入HttpServletResponse错误" + e);
            e.printStackTrace();
        }
    }

}
